App.require(function () {
    var app = App.getCurrent();

    app.defineComponent("str-progress", {
        getDomObj: function () {
            this.attachDom("[role='indicator']", "indicator")
        },
        render: function (next) {
            this.computeData();
            this.fetch("index.html", function (text) {
                return next(this.renderHTML(text));
            })
        },
        computeData: function () {
            var property = this.property;
            property.type = property.type || "line";
            property.class = property.class || "";
            property.value = property.value ? parseFloat(property.value) : "";
            var computeClass = this.computeClass();
            if (computeClass) property.class = computeClass + " " + property.class;
            property.max = property.max ? parseFloat(property.max) : 100;
            this.data.loaded = property.value ? parseFloat(property.value / property.max * 100) : 0;
        },
        computeClass: function () {
            var property = this.property;
            var loadingStr = property.value ? "loaded" : "loading";
            if (property.type === "circle") {
                return "circle-" + loadingStr;
            } else if (property.type === "line") {
                return "line-progress-" + loadingStr;
            }
        },
        setPercent: function (percent) {
            var property = this.property,
                container = this.domList.indicator,
                classList = container.classList,
                oldValue = property.value,
                oldClass = this.computeClass(),
                max = property.max;

            property.value = max * percent;
            var newClass = this.computeClass();
            if (!oldValue) {
                classList.remove(oldClass);
                classList.add(newClass);
            }
            var loaded = parseFloat(percent * 100);
            container.style.setProperty("animation-delay", "-" + loaded + "s");
        },
        get type() {
            return this.property.type;
        },
        get value() {
            return this.property.value;
        },
        set value(val) {
            if (val == this.property.value) return;
            var max = this.property.max, indicator = this.domList.indicator;
            if (this.property.value && val) {
                this.property.value = val;
                var loaded = parseFloat(val / max * 100);
                indicator.style.setProperty("animation-delay", "-" + loaded + "s");
            }
            else {
                var oldClass = this.computeClass();
                this.property.value = val;
                var newClass = this.computeClass();
                indicator.classList.remove(oldClass);
                indicator.classList.add(newClass);

                if (val) {
                    var loaded = parseFloat(val / max * 100);
                    indicator.style.setProperty("animation-delay", "-" + loaded + "s");
                }
            }
        },
        get max() {
            return this.property.max;
        },
        set max(value) {
            if (value === this.property.max) return;

            var val = this.property.value;
            this.property.max = max;
            if (val) {
                var loaded = parseFloat(val / max * 100);
                this.domList.indicator.style.setProperty("animation-delay", "-" + loaded + "s");
            }
        },
        get className() {
            return this.property.class;
        },
        set className(value) {
            if (this.property.class === value) return;
            var classList = this.domList.indicator.classList;
            var oldList = this.property.class.split(/\s+/g);
            var newList = value.split(/\s+/g);
            for (var i = 0; i < oldList.length; i++) {
                if (oldList[i]) classList.remove(oldList[i]);
            }
            for (i = 0; i < newList.length; i++) {
                if (newList[i]) classList.add(newList[i]);
            }
            this.property.class = value;
        }
    });
});